package com.zbkj.crmeb.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.PageParamRequest;
import com.constants.Constants;
import com.crmeb.core.exception.CrmebException;
import com.github.pagehelper.PageHelper;
import com.utils.CrmebUtil;
import com.utils.ProductConvertUtil;
import com.zbkj.crmeb.enums.CouponUserTypeEnum;
import com.zbkj.crmeb.marketing.model.StoreCoupon;
import com.zbkj.crmeb.marketing.service.StoreCouponService;
import com.zbkj.crmeb.store.dao.ChannelIntegralProductConfigDao;
import com.zbkj.crmeb.store.dto.ChannelIntegralProductConfigDTO;
import com.zbkj.crmeb.store.model.ChannelIntegralExchange;
import com.zbkj.crmeb.store.model.ChannelIntegralProductConfig;
import com.zbkj.crmeb.store.model.StoreProduct;
import com.zbkj.crmeb.store.service.ChannelIntegralExchangeService;
import com.zbkj.crmeb.store.service.ChannelIntegralProductConfigService;
import com.zbkj.crmeb.store.service.StoreProductService;
import com.zbkj.crmeb.system.service.SystemAdminService;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.model.UserAddress;
import com.zbkj.crmeb.user.model.UserBill;
import com.zbkj.crmeb.user.service.UserAddressService;
import com.zbkj.crmeb.user.service.UserBillService;
import com.zbkj.crmeb.user.service.UserService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ChannelIntegralProductConfigServiceImpl extends ServiceImpl<ChannelIntegralProductConfigDao, ChannelIntegralProductConfig> implements ChannelIntegralProductConfigService {

    @Autowired
    private StoreProductService storeProductService;
    @Autowired
    private StoreCouponService storeCouponService;
    @Autowired
    private SystemAdminService systemAdminService;
    @Autowired
    private ChannelIntegralExchangeService channelIntegralExchangeService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserBillService userBillService;
    @Autowired
    private UserAddressService userAddressService;

    /**
     * 功能描述: 获取商户积分商城商品设置
     * @Param: [dto, pageParamRequest]
     * @Return: java.util.List<com.zbkj.crmeb.store.dto.ChannelIntegralProductConfigDTO>
     * @Author: wangzh
     * @Date: 2023/2/27 15:56
     */
    @Override
    public List<ChannelIntegralProductConfigDTO> getIntegralProductConfig(ChannelIntegralProductConfigDTO dto, PageParamRequest pageParamRequest, Boolean isApp) {
        // 分页查询
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        LambdaQueryWrapper<ChannelIntegralProductConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChannelIntegralProductConfig::getMerId, dto.getMerId());
        // 积分商品搜索
        if (Objects.nonNull(dto.getId())) {
            queryWrapper.eq(ChannelIntegralProductConfig::getId, dto.getId());
        }
        // 活动状态查询
        if (Objects.nonNull(dto.getStatus())) {
            queryWrapper.eq(ChannelIntegralProductConfig::getStatus, dto.getStatus());
        }
        queryWrapper.orderByAsc(ChannelIntegralProductConfig::getSort);
        if (isApp) {
            queryWrapper.eq(ChannelIntegralProductConfig::getStatus, 1);
        }
        List<ChannelIntegralProductConfig> channelIntegralProductConfigs = this.list(queryWrapper);
        if (CollectionUtils.isEmpty(channelIntegralProductConfigs)) {
            return new ArrayList<>();
        }
        // 商品与优惠券对应的集合
        Map<Integer, List<ChannelIntegralProductConfig>> map = channelIntegralProductConfigs.stream().collect(Collectors.groupingBy(ChannelIntegralProductConfig::getProductType));
        // 积分商品类型为商品时，查询商品信息
        Map<Integer, StoreProduct> storeProductMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(map.get(1))) {
            // 商品ids
            List<Integer> productIds = map.get(1).stream().map(ChannelIntegralProductConfig::getIntegralProduct).collect(Collectors.toList());
            List<StoreProduct> listInIds = storeProductService.getListInIds(productIds);
            storeProductMap = listInIds.stream().collect(Collectors.toMap(StoreProduct::getId, e -> e));
        }
        // 积分商品类型为优惠券时，查询优惠券信息
        Map<Integer, StoreCoupon> couponMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(map.get(2))) {
            List<Integer> couponIds = map.get(2).stream().map(ChannelIntegralProductConfig::getIntegralProduct).collect(Collectors.toList());
            List<StoreCoupon> storeCoupons = storeCouponService.listByIds(couponIds);
            couponMap = storeCoupons.stream().collect(Collectors.toMap(StoreCoupon::getId, e -> e));
        }
        List<ChannelIntegralProductConfigDTO> channelIntegralProductConfigDTOS = new ArrayList<>();
        for (ChannelIntegralProductConfig channelIntegralProductConfig : channelIntegralProductConfigs) {
            ChannelIntegralProductConfigDTO channelIntegralProductConfigDTO = new ChannelIntegralProductConfigDTO();
            BeanUtils.copyProperties(channelIntegralProductConfig, channelIntegralProductConfigDTO);
            switch (channelIntegralProductConfig.getProductType()) {
                // 积分商品为商品
                case 1:
                    channelIntegralProductConfigDTO.setIntegralProduct(storeProductMap.get(channelIntegralProductConfig.getIntegralProduct()));
                    break;
                // 积分商品为优惠券
                case 2:
                    channelIntegralProductConfigDTO.setIntegralProduct(couponMap.get(channelIntegralProductConfig.getIntegralProduct()));
                    break;
            }
            channelIntegralProductConfigDTOS.add(channelIntegralProductConfigDTO);
        }

        return channelIntegralProductConfigDTOS;
    }

    /**
     * 功能描述: 保存/更新积分设置内容
     * @Param: [dto]
     * @Return: java.lang.Boolean
     * @Author: wangzh
     * @Date: 2023/2/27 17:00
     */
    @Override
    public Boolean saveOrUpdateIntegralProduct(ChannelIntegralProductConfigDTO dto) {
        ChannelIntegralProductConfig channelIntegralProductConfig = new ChannelIntegralProductConfig();
        BeanUtils.copyProperties(dto, channelIntegralProductConfig);
        channelIntegralProductConfig.setIntegralProduct((Integer) dto.getIntegralProduct());
        channelIntegralProductConfig.setCreateUser(systemAdminService.getAdminId());
        if (Objects.nonNull(dto.getStatus()) && dto.getStatus() == 1) {
            channelIntegralProductConfig.setShelfTime(new Date());
        }
        return this.saveOrUpdate(channelIntegralProductConfig);
    }

    /**
     * 功能描述: 商品上架/下架
     * @Param: [id, status]
     * @Return: java.lang.Boolean
     * @Author: wangzh
     * @Date: 2023/2/27 17:11
     */
    @Override
    public Boolean updateStatus(Integer id, Integer status) {
        return this.update(Wrappers.<ChannelIntegralProductConfig>lambdaUpdate()
                .eq(ChannelIntegralProductConfig::getId, id)
                .set(ChannelIntegralProductConfig::getStatus, status)
                .set(status == 1, ChannelIntegralProductConfig::getShelfTime, new Date()));
    }

    /**
     * 功能描述: 积分商城下拉列表
     * @Param: [merId]
     * @Return: java.util.List<com.zbkj.crmeb.store.dto.ChannelIntegralProductConfigDTO>
     * @Author: wangzh
     * @Date: 2023/2/27 17:37
     */
    @Override
    public List<ChannelIntegralProductConfigDTO> getList(Integer merId) {
        List<ChannelIntegralProductConfig> list = this.list(Wrappers.<ChannelIntegralProductConfig>lambdaQuery()
                .eq(ChannelIntegralProductConfig::getMerId, merId));
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        // 商品类型对应的集合
        Map<Integer, List<ChannelIntegralProductConfig>> map = list.stream().collect(Collectors.groupingBy(ChannelIntegralProductConfig::getProductType));
        // 商品id与商品名称的映射
        Map<Integer, String> productNameMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(map.get(1))) {
            List<Integer> productIds = map.get(1).stream().map(ChannelIntegralProductConfig::getIntegralProduct).collect(Collectors.toList());
            List<StoreProduct> listInIds = storeProductService.getListInIds(productIds);
            productNameMap = listInIds.stream().collect(Collectors.toMap(StoreProduct::getId, StoreProduct::getStoreName));
        }
        // 优惠券id与商品名称的映射
        Map<Integer, String> couponNameMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(map.get(2))) {
            List<Integer> couponIds = map.get(2).stream().map(ChannelIntegralProductConfig::getIntegralProduct).collect(Collectors.toList());
            List<StoreCoupon> storeCoupons = storeCouponService.listByIds(couponIds);
            couponNameMap = storeCoupons.stream().collect(Collectors.toMap(StoreCoupon::getId, StoreCoupon::getName));
        }
        List<ChannelIntegralProductConfigDTO> channelIntegralProductConfigDTOS = new ArrayList<>();
        for (ChannelIntegralProductConfig channelIntegralProductConfig : list) {
            ChannelIntegralProductConfigDTO dto = new ChannelIntegralProductConfigDTO();
            dto.setId(channelIntegralProductConfig.getId());
            switch (channelIntegralProductConfig.getProductType()) {
                case 1:
                    dto.setIntegralProduct(productNameMap.get(channelIntegralProductConfig.getIntegralProduct()));
                    break;
                case 2:
                    dto.setIntegralProduct(couponNameMap.get(channelIntegralProductConfig.getIntegralProduct()));
                    break;
            }
            channelIntegralProductConfigDTOS.add(dto);
        }
        return channelIntegralProductConfigDTOS;
    }

    /**
     * 功能描述: 通过id删除
     * @Param: [id]
     * @Return: java.lang.Boolean
     * @Author: wangzh
     * @Date: 2023/2/28 13:54
     */
    @Override
    public Boolean deleteIntegralProduct(Integer id) {
        return this.remove(Wrappers.<ChannelIntegralProductConfig>lambdaQuery()
                .eq(ChannelIntegralProductConfig::getId, id));
    }

    /**
     * 功能描述: 兑换商品
     * @Param: [id, attrValueId, addressId, exchangeIntegral]
     * @Return: java.lang.Boolean
     * @Author: wangzh
     * @Date: 2023/3/6 15:25
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean exchangeProduct(Integer id, String attrValueId, Integer addressId) {
        // 兑换用户信息
        User user = userService.getInfoException();
        // 兑换商品的信息
        ChannelIntegralProductConfig one = this.getById(id);
        if (Objects.isNull(one)) {
            throw new CrmebException("兑换商品不存在");
        }
        // 判断兑换商品的类型
        if (one.getProductType() == 1) {
            // 库存扣减结果
            boolean result = storeProductService.decProductStock(one.getIntegralProduct(), 1, attrValueId, 0, null);
            if (!result) {
                throw new CrmebException("商品已兑完！");
            }
        } else if (one.getProductType() == 2){
            // 进行优惠券发放
            Boolean result = storeCouponService.bindCouponByUser(Arrays.asList(user.getUid()), one.getIntegralProduct(), CouponUserTypeEnum.SEND);
            if (!result) {
                throw new CrmebException("商品已兑完！");
            }
        }
        BigDecimal exchangeIntegral = new BigDecimal(one.getNeedIntegral());
        // 兑换订单信息保存
        ChannelIntegralExchange exchange = new ChannelIntegralExchange();
        exchange.setOrderId(CrmebUtil.getOrderNo(Constants.PAY_TYPE_INTEGRAL));
        exchange.setUid(user.getUid());
        exchange.setUserName(user.getNickname());
        exchange.setUserPhone(user.getPhone());
        exchange.setProductType(one.getProductType());
        exchange.setProductId(one.getIntegralProduct());
        exchange.setExchangeIntegral(exchangeIntegral);
        exchange.setMerId(user.getMerId());
        exchange.setStatus(2);
        exchange.setSourceSkuId(attrValueId);
        // 商品为待发货状态，优惠券直接发放
        if (Objects.nonNull(addressId)) {
            UserAddress userAddress = userAddressService.getById(addressId);
            exchange.setUserAddress(userAddress.getProvince() + userAddress.getCity() + userAddress.getDistrict() + userAddress.getDetail());
            exchange.setStatus(1);
        }
        channelIntegralExchangeService.save(exchange);
        // 扣减用户积分
        BigDecimal integral = user.getIntegral().subtract(exchangeIntegral);
        if (integral.compareTo(BigDecimal.ZERO) < 0) {
            throw new CrmebException("积分不足！");
        }
        user.setIntegral(integral);
        userService.updateBase(user);
        // 积分日志
        saveIntegralLog(user.getUid(), exchangeIntegral, user.getIntegral());
        return true;
    }

    /**
     * 功能描述: 积分记录
     *
     * @Param: [uid, number, balance]
     * @Return: void
     * @Author: wangzh
     * @Date: 2023/3/2 10:23
     */
    private void saveIntegralLog(Integer uid, BigDecimal number, BigDecimal balance) {
        UserBill userBill = new UserBill();
        userBill.setUid(uid).setPm(0).setTitle("积分商城兑换").setCategory(Constants.USER_BILL_CATEGORY_INTEGRAL)
                .setType("exchange").setNumber(number).setBalance(balance)
                .setMark("积分商城兑换物品减少了" + number);
        userBillService.save(userBill);
    }

}
